package sf.dynamicsql.mapper;

import org.mybatis.dynamic.sql.select.SelectModel;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import sf.common.wrapper.Page;
import sf.core.DBObject;
import sf.database.dao.DBClient;
import sf.database.dao.DBContext;
import sf.database.dialect.DBDialect;
import sf.database.meta.MetaHolder;
import sf.database.meta.TableMapping;
import sf.dynamicsql.DynamicSqlTable;

import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class DynmicSQLMapperImpl<T extends DBObject> implements DynmicSQLMapper<T> {
    protected DBClient client;
    protected Class<T> domainClass;

    public DynmicSQLMapperImpl(DBClient client, Class<T> domainClass) {
        this.client = client;
        this.domainClass = domainClass;
    }

    @Override
    public DynamicSqlTable dynmicSQLTable() {
        DBDialect dialect = client.getDialect(false);
        TableMapping tm = MetaHolder.getMeta(domainClass);
        return new DynamicSqlTable((Class<? extends DBObject>) tm.getThisType(), null, dialect);
    }

    @Override
    public DynamicSqlTable dynmicSQLTable(DBContext context) {
        DBDialect dialect = client.getDialect(false);
        TableMapping tm = MetaHolder.getMeta(domainClass);
        return new DynamicSqlTable((Class<? extends DBObject>) tm.getThisType(), context, dialect);
    }

    @Override
    public List<T> selectList(SelectStatementProvider provider) {
        return client.getDynmicSQL().selectList(domainClass, provider);
    }

    @Override
    public Page<T> selectPage(SelectStatementProvider provider, int start, int limit) {
        return client.getDynmicSQL().selectPage(start, limit, domainClass, provider);
    }

    @Override
    public <S> S selectOne(SelectStatementProvider provider, Class<S> clz) {
        return client.getDynmicSQL().selectOne(clz, provider);
    }

    @Override
    public T selectOne(SelectStatementProvider provider) {
        return client.getDynmicSQL().selectOne(domainClass, provider);
    }

    @Override
    public void selectIterator(Consumer<Iterable<T>> ormIt, SelectStatementProvider provider) {
        client.getDynmicSQL().selectIterator(ormIt, domainClass, provider);
    }

    @Override
    public void selectStream(Consumer<Stream<T>> ormStream, SelectStatementProvider provider) {
        client.getDynmicSQL().selectStream(ormStream, domainClass, provider);
    }

    @Override
    public List<T> selectList(SelectModel selectModel) {
        return client.getDynmicSQL().selectList(domainClass, selectModel);
    }

    @Override
    public Page<T> selectPage(SelectModel selectModel, int start, int limit) {
        return client.getDynmicSQL().selectPage(start, limit, domainClass, selectModel);
    }

    @Override
    public <S> S selectOne(SelectModel selectModel, Class<S> clz) {
        return client.getDynmicSQL().selectOne(clz, selectModel);
    }

    @Override
    public T selectOne(SelectModel selectModel) {
        return client.getDynmicSQL().selectOne(domainClass, selectModel);
    }

    @Override
    public void selectIterator(Consumer<Iterable<T>> ormIt, SelectModel selectModel) {
        client.getDynmicSQL().selectIterator(ormIt, domainClass, selectModel);
    }

    @Override
    public void selectStream(Consumer<Stream<T>> ormStream, SelectModel selectModel) {
        client.getDynmicSQL().selectStream(ormStream, domainClass, selectModel);
    }
}
